﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace KATS_Client.UI
{
    /// <summary>
    /// A list view box that is drag and dropable
    /// </summary>
    public class ListViewDragable : ListView
    {
        /// <summary>
        /// Create a draggable list view box
        /// </summary>
        public ListViewDragable()
            : base()
        {

        }

        /// <summary>
        /// Select all the items
        /// </summary>
        public void SelectAll()
        {
            SelectedIndexCollection c = new SelectedIndexCollection(this);

            for (int i = 0; i < this.Items.Count; i++)
                c.Add(i);
        }

        /// <summary>
        /// Mouse pressed
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            List<Client.FileSystemObject> files = new List<Client.FileSystemObject>();

            foreach (ListViewItem lvi in this.SelectedItems)
            {
                files.Add((Client.FileSystemObject)lvi.Tag);
            }

            if (this.SelectedItems.Count != 0)
            {
                // then there is a selected item
                // now check that the mouse has selected at least 1 of the selected items
                Point clientPoint = base.PointToClient(new Point(e.X, e.Y));
                ListViewItem hoveredItem = base.GetItemAt(clientPoint.X, clientPoint.Y);

                if (hoveredItem != null)
                {
                    Client.FileSystemObject item = (Client.FileSystemObject)hoveredItem.Tag;
                    string item_string = item.ToString();

                    //check all the items that the selected item is 1 one of them
                    bool found = false;

                    foreach (Client.FileSystemObject f in files)
                    {
                        if (item_string == f.ToString())
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        DoDragDrop(files, DragDropEffects.Move);
                    }
                }
            }
            base.OnMouseDown(e);
        }

        /// <summary>
        /// Mouse released
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
        }



        /// <summary>
        /// The dragged objects have been dropped
        /// </summary>
        /// <param name="drgevent"></param>
        protected override void OnDragDrop(DragEventArgs drgevent)
        {
            Point clientPoint = base.PointToClient(new Point(drgevent.X, drgevent.Y));
            ListViewItem hoveredItem = base.GetItemAt(clientPoint.X, clientPoint.Y);

            Client.FileSystemObject target = null;
            List<Client.FileSystemObject> sourceFiles = (List<Client.FileSystemObject>)drgevent.Data.GetData(typeof(List<Client.FileSystemObject>));

            if (hoveredItem == null)
            {
                // then add it to the current page of the the listview
                Tab tab = (Tab)this.Tag;
                target = tab.Directory;
            }
            else
            {
                // then if this is a directory, add it inside the directory, 
                // else add it to the current directory
                Client.FileSystemObject hoveredItemData = (Client.FileSystemObject)hoveredItem.Tag;
                if (hoveredItemData.IsDirectory && !hoveredItemData.IsMyComputer)
                {
                    // then this is a directory
                    target = hoveredItemData;
                }
                else if (hoveredItemData.IsFile && !hoveredItemData.IsMyComputer)
                {
                    // then this is a file
                    Tab tab = (Tab)this.Tag;
                    target = tab.Directory;
                }
            }

            // now queue the move events
            Threaded_Queuing_MoveCopy moveaction = new Threaded_Queuing_MoveCopy(sourceFiles, target, false);
            moveaction.Perform();

            Console.WriteLine("Source : " + sourceFiles[0].Location);
            Console.WriteLine("Target : " + target.Location);


            base.OnDragDrop(drgevent);
        }

        /// <summary>
        /// While dragging the object over something
        /// </summary>
        /// <param name="drgevent"></param>
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            // get the List view item that is being hovered over
            Point clientPoint = base.PointToClient(new Point(drgevent.X, drgevent.Y));
            ListViewItem hoveredItem = base.GetItemAt(clientPoint.X, clientPoint.Y);

            if (hoveredItem != null)
            {
                Client.FileSystemObject hoverObject = (Client.FileSystemObject)hoveredItem.Tag;

                List<Client.FileSystemObject> sourceFiles = (List<Client.FileSystemObject>)drgevent.Data.GetData(typeof(List<Client.FileSystemObject>));

                // check all the data files that the user is not attempting to put
                // the files into itself
                bool found = false;
                string currentString = hoverObject.ToString();
                foreach (Client.FileSystemObject fso in sourceFiles)
                {
                    if (currentString == fso.ToString())
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    // then the dragged item is not over itself
                    drgevent.Effect = DragDropEffects.Move;
                }
                else
                {
                    // item found is itself
                    drgevent.Effect = DragDropEffects.None;
                }
            }
            else
            {
                // then not over an item currently
                drgevent.Effect = DragDropEffects.Move;
            }
            base.OnDragOver(drgevent);
        }

    }
}
